package net.seehope.foodie.controller;

import java.util.concurrent.Callable;

import org.n3r.idworker.Sid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;

import net.seehope.foodie.controller.async.DeferredResultHolder;
import net.seehope.foodie.controller.async.MockQueue;



//异步的控制层
@RestController
@RequestMapping("/asyn")
public class AsynController {
	
	private static final Logger log = LoggerFactory.getLogger(AsynController.class);

	@Autowired
	private MockQueue mockQueue;
	
	@Autowired
	private Sid sid;
	
	@Autowired
	private DeferredResultHolder deferredResultHolder;

	
	//异步线程控制器
	//通过id查找订单
	//要返回的值的类型在Callable的泛型里面写，要返回String就写Callable<String>
	@GetMapping("/{OrderId}")
	//这个OrderId其实没用
	
	//应用一与应用二是互相"看不到"的，在"看不到"的情况下取返回值，使用DeferredResult，跟下面的Callable不一样
	public DeferredResult<String> getOrder(@PathVariable String OrderId){
		
		log.info("-----主线程开始-----");
		
		String orderString = sid.nextShort();
		//下单
		mockQueue.setPlaceOrder(orderString);
		
		//这是最终返回的结果，直接输出是没有值的
		DeferredResult<String> result = new DeferredResult<String>();
		
		deferredResultHolder.getMap().put(orderString, result);
		
		
		/*
		 * 要求返回的必须是Callable对象，而原本需要返回的类型则放在泛型当中。
		 * 
		 * 所有控制层本身的逻辑写在下面
		 * 
		 * Callable<String> result = new Callable<String>() {
		 * 
		 * @Override public String call() throws Exception { 
		 * 
		 * log.info("---副线程开始---");
		 * 
		 * Thread.sleep(2000);
		 * 
		 * log.info("---副线程结束---");
		 * 
		 * return "success:"+sid.nextShort();
		 * 
		 * }
		 * 
		 * };
		 */
		
		log.info("---主线程结束---");
		return result;
		
		
		/*
		 * 上面注释内的运行结果可以看出
		 * 主线程和副线程分开执行了
		 * 
		 * 主线程负责分发请求，分发完之后，把事情交给副线程去处理
		 * 副线程通知主线程把结果带出去，返回到前端
		 * 
		 * 可是，这里的副线程是由主线程创建的。
		 */
		
		
		
	}

}
